home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
comm
/
mail
/
Mutt089src.lha
/
Mutt-0.89i-AMIGA
/
src
/
hook.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-28
|
6KB
|
264 lines
/*
* Copyright (C) 1996-8 Michael R. Elkins <me@cs.hmc.edu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "mutt.h"
#include "mutt_regex.h"
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
typedef struct hook
{
REGEXP rx;
char *command;
struct hook *next;
int type;
} HOOK;
static HOOK *Hooks = NULL;
int mutt_parse_hook (const char *s, void *data, char *err, size_t errlen)
{
HOOK *ptr;
char expn[LONG_STRING];
char command[LONG_STRING];
char pattern[STRING];
int type = (int) data;
regex_t *rx;
int rc, not = 0, flags = 0;
if (*s == '!')
{
s++;
SKIPWS (s);
not = 1;
}
s = mutt_extract_token (pattern, sizeof (pattern), s, expn, sizeof (expn), 0);
if (!s)
{
strfcpy (err, "too few arguments", errlen);
return (-1);
}
s = mutt_extract_token (command, sizeof (command), s, expn, sizeof (expn),
(type == M_FOLDERHOOK || type == M_SENDHOOK) ?
(M_SPACE | M_BACKSLASH) : 0);
if (!*command)
{
strfcpy (err, "too few arguments", errlen);
return (-1);
}
if (s)
{
strfcpy (err, "too many arguments", errlen);
return (-1);
}
if (type == M_FOLDERHOOK || type == M_MBOXHOOK)
mutt_expand_path (pattern, sizeof (pattern));
if (type == M_MBOXHOOK || type == M_SAVEHOOK || type == M_FCCHOOK)
mutt_expand_path (command, sizeof (command));
/* check to make sure that a matching hook doesn't already exist */
for (ptr = Hooks; ptr; ptr = ptr->next)
{
if (ptr->type == type && ptr->rx.not == not &&
!strcmp (pattern, ptr->rx.pattern) &&
!strcmp (command, ptr->command))
return 0; /* skip it */
if (!ptr->next)
break;
}
if (type == M_SENDHOOK || type == M_SAVEHOOK || type == M_FCCHOOK)
flags |= REG_ICASE;
rx = safe_malloc (sizeof (regex_t));
if ((rc = REGCOMP (rx, pattern, flags)) != 0)
{
regerror (rc, rx, err, errlen);
regfree (rx);
safe_free ((void **) &rx);
return (-1);
}
if (ptr)
{
ptr->next = safe_calloc (1, sizeof (HOOK));
ptr = ptr->next;
}
else
Hooks = ptr = safe_calloc (1, sizeof (HOOK));
ptr->type = type;
ptr->rx.pattern = safe_strdup (pattern);
ptr->rx.rx = rx;
ptr->rx.not = not;
ptr->command = safe_strdup (command);
return 0;
}
void mutt_folder_hook (char *path)
{
HOOK *tmp = Hooks;
char err[SHORT_STRING];
for (; tmp; tmp = tmp->next)
if (tmp->type == M_FOLDERHOOK)
{
if ((regexec (tmp->rx.rx, path, 0, NULL, 0) == 0) ^ tmp->rx.not)
{
if (mutt_parse_rc_line (tmp->command, err, sizeof (err)) == -1)
{
mutt_error ("%s", err);
sleep (1); /* pause a moment to let the user see the error */
return;
}
}
}
}
char *mutt_find_hook (int type, const char *pat)
{
HOOK *tmp = Hooks;
for (; tmp; tmp = tmp->next)
if (tmp->type == type)
{
if (regexec (tmp->rx.rx, pat, 0, NULL, 0) == 0)
return (tmp->command);
}
return (NULL);
}
void mutt_send_hook (ADDRESS *addr)
{
char buf[SHORT_STRING];
char err[SHORT_STRING];
ADDRESS *paddr;
HOOK *hook;
for (hook = Hooks; hook; hook = hook->next)
if (hook->type == M_SENDHOOK)
for (paddr = addr; paddr; paddr = paddr->next)
{
buf[0] = 0;
mutt_simple_address (buf, sizeof (buf), paddr);
if ((regexec (hook->rx.rx, buf, 0, NULL, 0) == 0) ^ hook->rx.not)
{
if (mutt_parse_rc_line (hook->command, err, sizeof (err)) != 0)
{
mutt_error ("%s", err);
sleep (1);
return;
}
break;
}
}
}
static int mutt_addr_hook (char *path, size_t pathlen, int type, ADDRESS *addr)
{
char buf[SHORT_STRING];
HOOK *hook;
ADDRESS *paddr;
for (hook = Hooks; hook; hook = hook->next)
if (hook->type == type)
for (paddr = addr; paddr; paddr = paddr->next)
{
buf[0] = 0;
mutt_simple_address (buf, sizeof (buf), paddr);
if ((regexec (hook->rx.rx, buf, 0, NULL, 0) == 0) ^ hook->rx.not)
{
strfcpy (path, hook->command, pathlen);
return 0;
}
}
return -1;
}
void mutt_default_save (char *path, size_t pathlen, ENVELOPE *env)
{
char tmp[_POSIX_PATH_MAX];
ADDRESS *adr;
if (mutt_addr_hook (path, pathlen, M_SAVEHOOK, env->from) == 0 ||
mutt_addr_hook (path, pathlen, M_SAVEHOOK, env->to) == 0 ||
mutt_addr_hook (path, pathlen, M_SAVEHOOK, env->cc) == 0)
return;
/* check to see if this is a mailing list */
for (adr = env->to; adr; adr = adr->next)
if (mutt_is_mail_list (adr))
break;
/* check the CC: list */
if (!adr)
{
for (adr = env->cc; adr; adr = adr->next)
if (mutt_is_mail_list (adr))
break;
}
/* pick default based upon sender */
if (!adr)
{
int fromMe = mutt_addr_is_user (env->from);
if (!fromMe && env->reply_to && env->reply_to->mailbox)
adr = env->reply_to;
else if (!fromMe && env->from && env->from->mailbox)
adr = env->from;
else if (env->to && env->to->mailbox)
adr = env->to;
else if (env->cc && env->cc->mailbox)
adr = env->cc;
}
mutt_safe_path (tmp, sizeof (tmp), adr);
snprintf (path, pathlen, "=%s", tmp);
}
void mutt_select_fcc (char *path, size_t pathlen, ENVELOPE *env)
{
ADDRESS *adr;
char buf[_POSIX_PATH_MAX];
if (mutt_addr_hook (path, pathlen, M_FCCHOOK, env->to) == 0 ||
mutt_addr_hook (path, pathlen, M_FCCHOOK, env->cc) == 0)
return;
if ((option (OPTSAVENAME) || option (OPTFORCENAME)) &&
(env->to || env->cc || env->bcc))
{
adr = env->to ? env->to : (env->cc ? env->cc : env->bcc);
mutt_safe_path (buf, sizeof (buf), adr);
snprintf (path, pathlen, "%s/%s", Maildir, buf);
if (option (OPTFORCENAME) || access (path, W_OK) == 0)
return;
}
strfcpy (path, Outbox, pathlen);
}